package com.windsea.relationshipmining.services;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Handler;
import android.provider.CallLog.Calls;
import android.util.Log;

import com.windsea.relationshipmining.api.ContactApi;
import com.windsea.relationshipmining.database.DBUserData;

/** This class detects newly logged phone calls. **/
public class PhoneWatcher extends ContentObserver {
	// Initialize constants and variables
	private static final String TAG = "CallWatcher";
	private Context context;
	private DBUserData dbUserData;
	// Specify formatting of data and time
	SimpleDateFormat formatdatetime = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	/**
	 * Constructor needed for content observers.
	 * 
	 * @param handler
	 * @param context
	 */
	public PhoneWatcher(Handler handler, Context context) {
		super(handler);
		this.context = context;
	}

	/**
	 * This method is called upon content observer change notifications.
	 * 
	 * @param selfChange
	 */
	@Override
	public void onChange(boolean selfChange) {
		super.onChange(selfChange);
		Log.d(TAG, "Phone event actived");
		queryCallLog();
	}

	/**
	 * This method queries the call log database for new calls.
	 */
	private void queryCallLog() {
		// Query the the call database
		Cursor callCursor = null;
		String[] callProj = new String[] { Calls._ID, Calls.NUMBER,
				Calls.CACHED_NAME, Calls.DURATION, Calls.DATE,
				Calls.CACHED_NUMBER_TYPE, Calls.TYPE };
		try {
			callCursor = context.getContentResolver().query(Calls.CONTENT_URI,
					callProj, null, null, Calls.DATE + " DESC");
		} catch (Exception e) {
			Log.e(TAG, "Unable to query CallLog content provider");
			return;
		}

		// Parse query results
		if (callCursor == null) {
			Log.e(TAG, "Unable to query CallLog content provider");
			return;
		}

		if (callCursor.moveToFirst() && callCursor.getCount() > 0) {

			// Get call event information
			int id = callCursor.getInt(callCursor.getColumnIndex(Calls._ID));
			String contactNumber = callCursor.getString(callCursor
					.getColumnIndex(Calls.NUMBER));
			String contactName = callCursor.getString(callCursor
					.getColumnIndex(Calls.CACHED_NAME));
			long duration = callCursor.getLong(callCursor
					.getColumnIndex(Calls.DURATION));
			Date callDate = new Date(callCursor.getLong(callCursor
					.getColumnIndex(Calls.DATE)));
			String numType = callCursor.getString(callCursor
					.getColumnIndex(Calls.CACHED_NUMBER_TYPE));
			int callType = callCursor.getInt(callCursor
					.getColumnIndex(Calls.TYPE));

			// Format datetime
			String datetime = formatdatetime.format(callDate);
			// Determine call direction
			String direction = "";
			if (callType == Calls.INCOMING_TYPE)
				direction = "Incoming";
			else if (callType == Calls.MISSED_TYPE)
				direction = "Missed";
			else
				direction = "Outgoing";

			// Check to make sure this is not an old call
			Calendar cal = Calendar.getInstance();
			cal.add(Calendar.MINUTE, -5);
			long fiveMinutesAgo = cal.getTimeInMillis();
			long endCallDate = callDate.getTime() + (duration * 1000L);
			if (endCallDate < fiveMinutesAgo)
				return;

			// Get call contact id

			dbUserData = new DBUserData(context);
			dbUserData.open();
			String contactId = dbUserData.getContactIdByPhonenumber(ContactApi
					.phoneNumberProcess(contactNumber));
			// Check to see if this
			// search is already in
			// the database
			if (contactId != null) {
				Cursor cursor = dbUserData.checkPhone(id);

				// Log new calls made & received
				if (cursor == null) {
					Log.e(TAG, "Unable to query events table");
					return;
				}

				if (cursor.getCount() == 0) {
					// Insert phone call event into DB
					dbUserData.insertCallLogs(id, datetime, contactId,
							String.valueOf(duration), direction);
					Log.i(TAG, "Direction: " + direction + " Number: "
							+ contactNumber + " Name: " + contactName
							+ " Duration: " + duration + " Date: " + datetime
							+ " NumType: " + numType + " ID: " + id);
				}

				cursor.close();
				dbUserData.close();
				dbUserData = null;
			}
		}
	}
}
